package top.sssd.auth.service.impl.role;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import top.sssd.auth.service.role.RoleService;
import top.sssd.auth.mapper.role.RoleMapper;
import top.sssd.auth.model.role.converter.RoleConverter;
import top.sssd.auth.model.role.entity.Role;
import top.sssd.auth.model.role.request.RoleQueryReq;
import top.sssd.auth.model.role.request.RoleSaveOrUpdateReq;
import top.sssd.auth.model.role.response.RoleResp;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Override
    public Page<RoleResp> queryPage(RoleQueryReq roleQueryReq) {
        Page<Role> page = new Page<>(roleQueryReq.getPageNum(), roleQueryReq.getPageSize());
        Page<Role> resultPage = commonQuery(roleQueryReq).page(page);
        List<RoleResp> resultList = resultPage.getRecords().parallelStream()
                .map(RoleConverter.INSTANCE::entityToResp)
                .toList();
        return new Page<RoleResp>()
                .setTotal(resultPage.getTotal())
                .setCurrent(resultPage.getCurrent())
                .setSize(resultPage.getSize())
                .setRecords(resultList);
    }

    @Override
    public List<RoleResp> queryRoleRespListByRoleReq(RoleQueryReq RoleQueryReq) {
        List<Role> list = commonQuery(RoleQueryReq).list();
        return list.parallelStream()
                .map(RoleConverter.INSTANCE::entityToResp)
                .toList();
    }

    private LambdaQueryChainWrapper<Role> commonQuery(RoleQueryReq roleQueryReq) {
        return this.lambdaQuery()
                .eq(ObjectUtil.isNotEmpty(roleQueryReq.getId()), Role::getId, roleQueryReq.getId())
                .eq(ObjectUtil.isNotEmpty(roleQueryReq.getName()), Role::getName, roleQueryReq.getName())
                .eq(ObjectUtil.isNotEmpty(roleQueryReq.getCode()), Role::getCode, roleQueryReq.getCode())
                .eq(ObjectUtil.isNotEmpty(roleQueryReq.getDescription()), Role::getDescription, roleQueryReq.getDescription())
                .eq(ObjectUtil.isNotEmpty(roleQueryReq.getStatus()), Role::getStatus, roleQueryReq.getStatus())
                .orderByDesc(Role::getUpdatedTime);
    }

    @Override
    public RoleResp getRoleRespById(Serializable id) {
        Role role = this.getById(id);
        if (Objects.nonNull(role)) {
            return RoleConverter.INSTANCE.entityToResp(role);
        }
        throw new RuntimeException("角色表不存在");
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean saveRoleReq(RoleSaveOrUpdateReq roleSaveOrUpdateReq) {
        Role role = RoleConverter.INSTANCE.saveOrUpdateRoleReqToEntity(roleSaveOrUpdateReq);
        return this.save(role);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean updateRoleReq(RoleSaveOrUpdateReq roleSaveOrUpdateReq) {
        Role role = RoleConverter.INSTANCE.saveOrUpdateRoleReqToEntity(roleSaveOrUpdateReq);
        return this.updateById(role);
    }
}

